package beans;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

public class DisplayingOffers {
	
	private ArrayList<MyOfferDisplay> offers;
	BasicDataSource ds;
	private ArrayList<Integer> amount;
	
	
	private UserOfferBean selectedOffer;
	private int currentlySelectedOffer;
	UserBean uBean;
	private int selectedAmount;
	private String reservationMsg;
	
	public DisplayingOffers(BasicDataSource ds, UserBean ub) {
		offers = new ArrayList<MyOfferDisplay>();
		this.ds = ds;
		uBean = ub;
	}
	
	public void loadDailyOffers()
	{
		Connection cnn = null;
		Statement stat = null;
		ResultSet rs = null;
		
		offers.clear();
		
		try {
			cnn = ds.getConnection();
			stat = cnn.createStatement();
			Date today = new Date();
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			String todayF = dateFormat.format(today);
			
			String getDailyOffers = "SELECT idOffers, title, aboutOffer, isEvent, price, hasDiscount, discountPrice, initialAmount, amountLeft, picture FROM offers WHERE "
									+ "offerStarts = '" + todayF + "' AND isValid = true AND amountLeft > 0";
			
//			String getDailyOffers = "SELECT idOffers, title, aboutOffer, isEvent, price, hasDiscount, discountPrice, initialAmount, amountLeft, picture FROM offers WHERE "
//					+ "offerStarts = DATE(NOW()) AND isValid = true AND amountLeft > 0";
			
			rs = stat.executeQuery(getDailyOffers);
			while(rs.next())
			{
				MyOfferDisplay oneOffer = new MyOfferDisplay();
				
				int offerId = rs.getInt("idOffers");
				oneOffer.setOfferId(offerId);
				
				String title = rs.getString("title");
				oneOffer.setTitle(title);
				
				String desc = rs.getString("aboutOffer");
				oneOffer.setDescription(desc);
				
				boolean event = rs.getBoolean("isEvent");
				oneOffer.setEvent(event);
				
				double price = rs.getDouble("price");
				oneOffer.setPrice(price);
				
				boolean discount = rs.getBoolean("hasDiscount");
				oneOffer.setHasDiscount(discount);
				
				double discPrice = rs.getDouble("discountPrice");
				oneOffer.setDiscountPrice(discPrice);
				
				int initAmount = rs.getInt("initialAmount");
				oneOffer.setInitialAmount(initAmount);
				
				int amountL = rs.getInt("amountLeft");
				oneOffer.setAmountLeft(amountL);
				
				//load picture
				String str = rs.getString("picture");
				int len = str.length();
				byte[] img = new byte[len];
				InputStream imgStream = rs.getBinaryStream("picture");
				OutputStream outS = null;
				File out = new File("E:\\Servers\\apache-tomcat-7.0.23\\webapps\\reservation-pia\\" + offerId + ".jpg");
				try {
					outS = new FileOutputStream(out);
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				}
				
				int i;
				while((i = imgStream.read(img)) > 0)
				{
					outS.write(img, 0, i);
				}
				
				outS.close();
				imgStream.close();
				offers.add(oneOffer);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally
		{
			if(cnn != null)
			{
				try {
					cnn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			
			if(stat != null)
			{
				try {
					stat.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			
			if(rs != null)
			{
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		
		
	}
	
	public void loadCurrentOffers()
	{
		Connection cnn = null;
		Statement stat = null;
		ResultSet rs = null;
		
		offers.clear();
		
		try {
			cnn = ds.getConnection();
			stat = cnn.createStatement();
			Date today = new Date();
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			String todayF = dateFormat.format(today);
			
			String getCurrentOffers = "SELECT idOffers, title, aboutOffer, isEvent, price, hasDiscount, discountPrice, initialAmount, amountLeft, picture FROM offers WHERE "
					+ "offerEnds > '" + todayF + "'  AND isValid = true AND amountLeft > 0";
			
			rs = stat.executeQuery(getCurrentOffers);
			while(rs.next())
			{
				MyOfferDisplay oneOffer = new MyOfferDisplay();
				
				int offerId = rs.getInt("idOffers");
				oneOffer.setOfferId(offerId);
				
				String title = rs.getString("title");
				oneOffer.setTitle(title);
				
				String desc = rs.getString("aboutOffer");
				oneOffer.setDescription(desc);
				
				boolean event = rs.getBoolean("isEvent");
				oneOffer.setEvent(event);
				
				double price = rs.getDouble("price");
				oneOffer.setPrice(price);
				
				boolean discount = rs.getBoolean("hasDiscount");
				oneOffer.setHasDiscount(discount);
				
				double discPrice = rs.getDouble("discountPrice");
				oneOffer.setDiscountPrice(discPrice);
				
				int initAmount = rs.getInt("initialAmount");
				oneOffer.setInitialAmount(initAmount);
				
				int amountL = rs.getInt("amountLeft");
				oneOffer.setAmountLeft(amountL);
				
				//load picture
				String str = rs.getString("picture");
				int len = str.length();
				byte[] img = new byte[len];
				InputStream imgStream = rs.getBinaryStream("picture");
				OutputStream outS = null;
				File out = new File("E:\\Servers\\apache-tomcat-7.0.23\\webapps\\reservation-pia\\" + offerId + ".jpg");
				try {
					outS = new FileOutputStream(out);
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				}
				
				int i;
				while((i = imgStream.read(img)) > 0)
				{
					outS.write(img, 0, i);
				}
				
				outS.close();
				imgStream.close();
				offers.add(oneOffer);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally
		{
			if(cnn != null)
			{
				try {
					cnn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			
			if(stat != null)
			{
				try {
					stat.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
	public String displayCurrentOffer()
	{
		selectedOffer = new UserOfferBean(ds);
		selectedOffer.loadData(currentlySelectedOffer);
		return "currentoffer";
	}
	
	public String goToReservation()
	{
		// just transfer to next page
		amount = new ArrayList<Integer>();
		for(int i = 1; i <= uBean.getBuyingParamRounded(); i++)
		{
			amount.add(new Integer(i));
		}
		return "reserve";
	}
	
	public String reserveOffer()
	{
		Connection cnn = null;
		
		try {
			cnn = ds.getConnection();
			cnn.setAutoCommit(false);
			if(alreadyReserved(uBean.getUserId(), currentlySelectedOffer, cnn))
			{
				//error
				cnn.rollback();
				reservationMsg = "Већ сте резервисали ову понуду.";
				return null;
			}
			if(!checkAndDecreaseAmountLeft(selectedAmount, currentlySelectedOffer, cnn))
			{
				cnn.rollback();
				reservationMsg = "Тренутно нема довољно понуда. Покушајте са мањим бројм понуда.";
				return null;
			}
			insertIntoReservationsTable(uBean.getUserId(), currentlySelectedOffer, selectedAmount, cnn);
		} catch (SQLException e) {
			e.printStackTrace();
			try {
				cnn.rollback();
			} catch (SQLException e1) {
				System.out.println("Unsuffesfull rollback");
				e1.printStackTrace();
			}
			return null;
		}
		
		try {
			cnn.commit();
		} catch (SQLException e) {
			System.out.println("Unsuffesfull commit");
			e.printStackTrace();
		}
		reservationMsg = "Успешно сте резервисали понуду.";
		return null;
	}
	
	private boolean checkAndDecreaseAmountLeft(int numberReserved, int offerId, Connection cnn) throws SQLException
	{
		Statement stat = null;
		ResultSet rs = null;
		
		stat = cnn.createStatement();
		String getCurrentAmount = "SELECT amountLeft FROM offers WHERE idOffers = " + offerId;
		rs = stat.executeQuery(getCurrentAmount);
		rs.next();
		int left = rs.getInt("amountLeft");
		if(left < numberReserved)
		{
			stat.close();
			rs.close();
			return false;
			//returns false if there's not enough offer instances
		}
		left -= numberReserved;
		stat.close();
		rs.close();
		stat = cnn.createStatement();
		String updateOffers = "UPDATE offers SET amountLeft = " + left + " WHERE idOffers = " + offerId;
		stat.executeUpdate(updateOffers);
		stat.close();
		return true;
		//returns true if successfull
	}
	
	private boolean alreadyReserved(int userId, int offerId, Connection con) throws SQLException
	{
		Statement stat = null;
		ResultSet rs = null;
		
		stat = con.createStatement();
		String checkIfReservatedQuery = "SELECT * FROM reservations WHERE idOffer = " + offerId + " AND idUser = " + userId;
		rs = stat.executeQuery(checkIfReservatedQuery);
		if(rs.next())
		{
			stat.close();
			return true;
		}
		stat.close();
		return false;
	}
	
	private void insertIntoReservationsTable(int idUser, int idOffer, int numberReserved, Connection conn) throws SQLException
	{
		PreparedStatement stat = null;
		String insertIntoReservations = "INSERT INTO reservations(idOffer, idUser, dateReserved, isConfirmed, numberReserved) VALUES (?, ?, ?, ?, ?)";
		stat = conn.prepareStatement(insertIntoReservations);
		
		stat.setInt(1, idOffer);
		stat.setInt(2, idUser);
		
		Date today = new Date();
		java.sql.Date todaySql = new java.sql.Date(today.getTime());
		stat.setDate(3, todaySql);
		stat.setBoolean(4, false);
		stat.setInt(5, numberReserved);
		stat.executeUpdate();
	}

	public ArrayList<MyOfferDisplay> getOffers() {
		return offers;
	}

	public void setOffers(ArrayList<MyOfferDisplay> offers) {
		this.offers = offers;
	}

	public int getCurrentlySelectedOffer() {
		return currentlySelectedOffer;
	}

	public void setCurrentlySelectedOffer(int currentlySelectedOffer) {
		this.currentlySelectedOffer = currentlySelectedOffer;
	}

	public UserOfferBean getSelectedOffer() {
		return selectedOffer;
	}

	public void setSelectedOffer(UserOfferBean selectedOffer) {
		this.selectedOffer = selectedOffer;
	}

	public int getSelectedAmount() {
		return selectedAmount;
	}

	public void setSelectedAmount(int selectedAmount) {
		this.selectedAmount = selectedAmount;
	}

	public ArrayList<Integer> getAmount() {
		return amount;
	}

	public void setAmount(ArrayList<Integer> amount) {
		this.amount = amount;
	}

	public String getReservationMsg() {
		return reservationMsg;
	}

	public void setReservationMsg(String reservationMsg) {
		this.reservationMsg = reservationMsg;
	}
	
	
}
